package org.phona.index;




import java.util.ArrayList;
import java.util.TreeMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

//import org.phona.object.Contact;


public class IndexNode {

	IndexNode parent;
	Character value;

	Map<Character,IndexNode> nodes = new TreeMap<Character,IndexNode>();
	List<String> objects = new ArrayList<String>();

	public IndexNode() {
		
	}
	
	public IndexNode(Character c) {		
		this.value = c;
	}

	public void insert(String stringToIndex,String objToIndex){
		if(stringToIndex.length()==0){
			objects.add(objToIndex);
		}else{
			Integer i=1;
			for (Character c : stringToIndex.toCharArray()){
				IndexNode current = nodes.get(c);
				if(current==null){
					current = new IndexNode(c);
					nodes.put(c, current);
					current.parent=this;
				}
				current.insertDeep(stringToIndex.substring(i), objToIndex);
				i++;
			}
		}
				
	}
	
	void insertDeep(String stringToIndex,String objToIndex){
		if(stringToIndex.length()==0){
			objects.add(objToIndex);
		}else{
			Character fc = stringToIndex.charAt(0);
			IndexNode current = nodes.get(fc);
			if(current==null){
				current = new IndexNode(fc);
				nodes.put(fc, current);
				current.parent=this;
			}
			current.insertDeep(stringToIndex.substring(1), objToIndex);
		}
				
	}

	public void search(String query,Set<String> result){
		if(query.length()==0){
			getAll(result);
			
		}else{
			IndexNode current = nodes.get(query.charAt(0));
			if(current!=null){
				current.search(query.substring(1), result);
			}
		}
	}
	
	public Set<String> search(String query){
		Set<String> result = new HashSet<String>();
		search(query,result);
		return result;
	}
	
	public void search(List<String> query,Map<String,List<String>> resultContainer){
		if(query.size()==0){
			Set<String> result = new HashSet<String>();
			getAll(result);
			for(String key : result){
				List<String> values= resultContainer.get(key);
				if(values==null){
					values=new ArrayList<String>();
					
				}
				values.add(getFullName().intern());
				resultContainer.put(key, values);
			}
		}else{
			String chars= query.get(0);
			
			for(Integer i=0,n=chars.length();i<n;i++){
				IndexNode current = nodes.get(chars.charAt(i));
				if(current!=null){
					current.search(query.subList(1, query.size()), resultContainer);
				}
			}
		}
	}
	
	String getFullName() {
		if(value==null){
			return ""; 
		}else{
			return parent.getFullName()+value;
		}
	}

	public Map<String,List<String>>  search(List<String> query){
		Map<String,List<String>> result = new TreeMap<String,List<String>>();
		search(query,result);
		return result;
	}
	
	public void getAll(Set<String> result){
		result.addAll(objects);
		for(IndexNode c : nodes.values()){
			c.getAll(result);
		}
	}
	
	public String display(String margin){
		StringBuffer sb = new StringBuffer();
		sb.append(margin+value+objects.toString());
		sb.append("\n");
		for(IndexNode c : nodes.values()){
			sb.append(c.display(margin+"  "));
			sb.append("\n");
		}
		return sb.toString();
	}
	
	
	public String displayAll(){
		if(value==null){
			return display("  ");			
		}else{
			return parent.displayAll();
		}
	}
	
	
	
	
	
}


